package com.b00t.client.view;

import java.util.List;

import com.b00t.client.ItemService;
import com.b00t.client.ItemServiceAsync;
import com.b00t.shared.Item;
import com.google.gwt.cell.client.ButtonCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.view.client.AsyncDataProvider;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.SingleSelectionModel;

public class ItemView extends Composite {

	interface ItemViewBinder extends UiBinder<FlowPanel, ItemView>{
		
	}

	@UiField(provided=true)
	CellTable itemCellTable;
	
	@UiField
	Button addItem;
	
	private ItemViewBinder ourBinder = GWT.create(ItemViewBinder.class);
	
	
	private final SingleSelectionModel<Item> itemSelection = new SingleSelectionModel<Item>();
	
	//TODO: Move this somewhere else..make the view dumb.
	private final ItemServiceAsync itemService = GWT.create(ItemService.class);
	
	public ItemView(){
		itemCellTable = new CellTable<Item>(10);
		//we have to bind the ui
		FlowPanel root = ourBinder.createAndBindUi(this);
		
		itemCellTable.setSelectionModel(itemSelection);
		itemCellTable.addColumn(new NameColumn(), "Name of the item");
		itemCellTable.addColumn(new IdColumn(), "Id");
		itemCellTable.addColumn(new ActionColumn(),"Action");
		
		fillData();		
		initWidget(root);
	}
	
	
	private void fillData() {
		//TODO: We need to refactor this part. No Asynch call in the view part. Use a presenter in the next iteration
		
//		Idea is to make MVP pattern.
//		Push the prester Object upto the View
//		Let the prestner take care of the logic part of view.
//		it this scenario it should be presenter.getItem. And Presenter will do the Asynch call --Rakesh
		itemCellTable.setRowCount(0);
		itemService.getItemList(new AsyncCallback<List<Item>>() {
			
			@Override
			public void onSuccess(List<Item> result) {
				Window.alert("RPC call success--getITemList");
				itemCellTable.setRowData(result);
			}
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Something wrong in RPC call");
			}
		});
	}

	@UiHandler("addItem")
	void addItem(ClickEvent event){
		Window.alert("Call add Item call");
		//TODO: We need to refactor this part. No Asynch call in the view part. Use a presenter in the next iteration
		itemService.addItem(new Item("Sample_new_itme", "001"), new AsyncCallback<Void>() {

			@Override
			public void onFailure(Throwable caught) {
				
			}

			@Override
			public void onSuccess(Void result) {
				fillData();
				//TODO: Yes...This is bad. 
//				    Create a AddItemEVent
//				    Fire it.
//				    Let the View listen the addITem event and update.
//					Create an evert handler. There should be eventbus for the app
			}
		});
	} 

	private class NameColumn extends Column<Item, String>{

		public NameColumn() {
			super(new TextCell());
		}

		@Override
		public String getValue(Item object) {
			return object.getName();
		}
	}
	
	private class IdColumn extends Column<Item, String>{

		public IdColumn() {
			super(new TextCell());
		}

		@Override
		public String getValue(Item object) {
			return object.getId();
		}
	}

	
	private class ActionColumn extends Column<Item, String>{

		public ActionColumn() {
			super(new ButtonCell());
		}

		@Override
		public String getValue(Item object) {
			//TODO: this is bad. Should update directly to widget
			return "Delete";
		}	
	}

	//TODO: Need to use this 
	private class ItemDataProvider extends AsyncDataProvider<Item>{

		@Override
		protected void onRangeChanged(HasData<Item> display) {
//			updateRowData(display, start, values);
		}
	}
	
	
}
